package com.ruoyi.system.utils;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.ruoyi.system.config.AlipayConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @ProjectName: back
 * @Package: com.ruoyi.system.utils
 * @ClassName: AlipayUtil
 * @Author: haiyue
 * @Description:
 * @Date: 2025/6/9 下午 7:40:48
 * @Version: 1.0
 */
@Component
public class AlipayUtil {
    @Autowired
    private AlipayConfig alipayConfig;

    /**
     * 生成支付宝支付页面
     * @param outTradeNo 商户订单号
     * @param subject 订单标题
     * @param totalAmount 订单金额(元)
     * @return 支付宝支付页面表单
     * @throws AlipayApiException
     */
    public String createPayPage(String outTradeNo, String subject, String totalAmount,String returnUrl,String notifyUrl) throws AlipayApiException {
        // 创建AlipayClient实例
        AlipayClient alipayClient = new DefaultAlipayClient(
                alipayConfig.gatewayUrl,
                alipayConfig.appId,
                alipayConfig.merchantPrivateKey,
                "json",
                alipayConfig.charset,
                alipayConfig.alipayPublicKey,
                alipayConfig.signType
        );

        // 创建API对应的request
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        // 在公共参数中设置回跳和通知地址
        alipayRequest.setReturnUrl(returnUrl);
        alipayRequest.setNotifyUrl(notifyUrl);

        // 创建业务参数模型
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setOutTradeNo(outTradeNo);
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        model.setTotalAmount(totalAmount);
        model.setSubject(subject);
        alipayRequest.setBizModel(model);

        // 调用SDK生成表单
        return alipayClient.pageExecute(alipayRequest).getBody();
    }

    /**
     * 查询订单状态
     * @param outTradeNo 商户订单号
     * @param tradeNo 支付宝交易号(选填)
     * @return 查询结果
     * @throws AlipayApiException
     */
    public AlipayTradeQueryResponse queryOrder(String outTradeNo, String tradeNo) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(
                alipayConfig.gatewayUrl,
                alipayConfig.appId,
                alipayConfig.merchantPrivateKey,
                "json",
                alipayConfig.charset,
                alipayConfig.alipayPublicKey,
                alipayConfig.signType
        );

        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setOutTradeNo(outTradeNo);
        model.setTradeNo(tradeNo);
        request.setBizModel(model);

        return alipayClient.execute(request);
    }

    /**
     * 订单退款
     * @param outTradeNo 商户订单号
     * @param tradeNo 支付宝交易号(选填)
     * @param refundAmount 退款金额(元)
     * @param refundReason 退款原因(选填)
     * @return 退款结果
     * @throws AlipayApiException
     */
    public AlipayTradeRefundResponse refundOrder(String outTradeNo, String tradeNo, String refundAmount, String refundReason) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(
                alipayConfig.gatewayUrl,
                alipayConfig.appId,
                alipayConfig.merchantPrivateKey,
                "json",
                alipayConfig.charset,
                alipayConfig.alipayPublicKey,
                alipayConfig.signType
        );

        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setOutTradeNo(outTradeNo);
        model.setTradeNo(tradeNo);
        model.setRefundAmount(refundAmount);
        model.setRefundReason(refundReason);
        request.setBizModel(model);

        return alipayClient.execute(request);
    }

    /**
     * 验证支付宝回调签名
     * @param request 回调请求
     * @return 验证结果
     * @throws AlipayApiException
     */
    public boolean verifySign(HttpServletRequest request) throws AlipayApiException {
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        // 调用SDK验证签名
        return AlipaySignature.rsaCheckV1(params, alipayConfig.alipayPublicKey, alipayConfig.charset, alipayConfig.signType);
    }
}
